﻿using fmtx.Framework.Web;
using NetCore.IWebBLL;
using NetCore.RedisCache;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;

namespace NetCore.RedisSession
{
    public class SessionService : ISession
    {
        private const string SESSIONUSER = "LogonSystemUser";
        private const string COOKIETOKEN = "syh-user-cook-id";
        private const string COOKIEENCRYKEY = "zxcvbnma";
        private const string SESSIONTOKEN = "SYH-Logon-TOKEN";

        private readonly int timeoutstr = Convert.ToInt32(ConfigurationManager.AppSettings["sessionTimeOut"]);
        private CacheService cache = new CacheService();

        public void Clear()
        {
            var keys = cache.Keys();
            if (keys != null && keys.Count > 0)
            {
                foreach (var item in keys)
                {
                    var user = cache.Get<ILoginUser>(item);
                    if (user.TimeOut.AddMinutes(timeoutstr) < DateTime.Now)
                    {
                        cache.Remove(item);
                        var list = cache.Get<Dictionary<string, string>>(item + "-KEYS");
                        if (list != null)
                        {
                            foreach (var key in list)
                            {
                                cache.Remove(item + key);
                            }
                        }
                        cache.Remove(item + "-KEYS");
                    }
                }
            }

        }

        public T Get<T>(Guid token)where T:ILoginUser
        {
            return cache.Get<T>(token.ToString());
        }

        public Guid LogToken(ILoginUser user)
        {
            var token = Guid.NewGuid();
            cache.Set(token.ToString(), user);
            return token;
        }

        public void Remove(Guid token)
        {
            cache.Remove(token.ToString());
        }

        public void UpdateTime(Guid token)
        {
            var user = Get<ILoginUser>(token);
            user.TimeOut = DateTime.Now;
            cache.Set(token.ToString(), user);
        }

        public T GetData<T>(string key)
        {
            var current = System.Web.HttpContext.Current;
            var token = current.Session[SESSIONTOKEN] + "";
            if (string.IsNullOrEmpty(token))
            {
                token = WebCookieHelper.GetCookie(COOKIETOKEN, COOKIEENCRYKEY);
            }
            return cache.Get<T>(token + key);
        }

        public void SetData<T>(string key, T data)
        {
            var current = System.Web.HttpContext.Current;
            var token = current.Session[SESSIONTOKEN] + "";
            if (string.IsNullOrEmpty(token))
            {
                token = WebCookieHelper.GetCookie(COOKIETOKEN, COOKIEENCRYKEY);
            }
            var list = cache.Get<Dictionary<string, string>>(token + "-KEYS");
            if (list == null)
            {
                list = new Dictionary<string, string>();
                list.Add(key, key);
                cache.Set(token + "-KEYS", list);
            }
            else
            {
                if (!list.ContainsKey(key))
                {
                    list.Add(key, key);
                    cache.Set(token + "-KEYS", list);
                }
            }
            cache.Set(token + key, data);
        }

        public void RemoveData(string key)
        {
            var current = System.Web.HttpContext.Current;
            var token = current.Session[SESSIONTOKEN] + "";
            if (string.IsNullOrEmpty(token))
            {
                token = WebCookieHelper.GetCookie(COOKIETOKEN, COOKIEENCRYKEY);
            }
            cache.Remove(token + key);
        }

        public void Update(Guid token, ILoginUser bean)
        {
            var user = Get<ILoginUser>(token);
            user.TimeOut = DateTime.Now;
            cache.Set(token.ToString(), user);
        }
    }
}
